package com.demo.service.impl;

import com.demo.dto.LeaveDTO;
import com.demo.dto.LeavePageQueryDTO;
import com.demo.mapper.CourseMapper;
import com.demo.mapper.LeaveMapper;
import com.demo.mapper.StudentMapper;
import com.demo.pojo.Classes;
import com.demo.pojo.Course;
import com.demo.pojo.Leave;
import com.demo.pojo.Student;
import com.demo.result.PageResult;
import com.demo.service.LeaveService;
import com.demo.vo.LeaveVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class LeaveServiceImpl implements LeaveService {

    @Autowired
    LeaveMapper leaveMapper;
    @Autowired
    CourseMapper courseMapper;
    @Autowired
    StudentMapper studentMapper;

    //新增假条
    public void save(LeaveDTO leaveDTO) {
        Leave leave=new Leave();
        BeanUtils.copyProperties(leaveDTO,leave);

        leave.setLeaveID(generateLeaveOrderNumber());
        String courseName=leaveDTO.getCourseName();
        System.out.println("course:"+courseName);
        Course course=courseMapper.selectByCourseName(courseName);
        System.out.println(course+"------------");
        leave.setCourseID(course.getCourseID());

        LocalDateTime applytime = LocalDateTime.now();
        leave.setApplytime(applytime);
        leave.setStatus("0");
        System.out.println(leave+"........");
        leaveMapper.addLeave(leave);
    }

    //删除假条
    public Boolean delete(String leaveID) {
        int rows= leaveMapper.delete(leaveID);
        System.out.println(rows+"个数");
        return rows>0;
    }

    //分页查询
    public PageResult pageQuery(LeavePageQueryDTO leavePageQueryDTO) {
        System.out.println(leavePageQueryDTO+"-------impl");
        System.out.println(leavePageQueryDTO.getClassName()+"%%%%%%%%%%%");


        PageHelper.startPage(leavePageQueryDTO.getPage(), leavePageQueryDTO.getPageSize());
        Page<LeaveVO> page = leaveMapper.pageQuery(leavePageQueryDTO);
        long total = page.getTotal();
        List<LeaveVO> records = page.getResult();
        return new PageResult(total, records);
    }

    //查询假条
    public Leave selectByLeaveID(String leaveID) {
        Leave leave=leaveMapper.selectByLeaveID(leaveID);
        return leave;
    }

    //审批假条
    @Transactional
    public void update(LeaveDTO leaveDTO) {
        LocalDateTime audittime=LocalDateTime.now();
        leaveDTO.setAudittime(audittime);
        leaveMapper.update(leaveDTO);
    }

    public String generateLeaveOrderNumber() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        int random = (int) (Math.random() * 1000); // 四位随机数
        return timestamp + String.format("%03d", random);
    }


    public ResponseEntity<byte[]> exportData(Map<String, String> params) throws JsonProcessingException {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Projects");
        PageResult pageResult = pageQuery((LeavePageQueryDTO) params);
        JSONObject checkedAllObject = new JSONObject(params.get("checkedall"));

        // 设置标题样式
        CellStyle titleStyle = workbook.createCellStyle();
        Font titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontHeightInPoints((short) 14);
        titleStyle.setFont(titleFont);
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 创建第一行并设置标题
        Row titleRow = sheet.createRow(0);
        Cell titleCell = titleRow.createCell(0);
        titleCell.setCellValue("请假名单");
        titleCell.setCellStyle(titleStyle);

        // 列顺序和列名映射
        List<String> orderedKeys = Arrays.asList(
                "leaveID", "courseID", "reason",
                "daynum", "stuNo", "applytime",
                "status", "audittime", "opinion"
        );
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("leaveID", "请假编号");
        headerMap.put("courseID", "课程编号");
        headerMap.put("reason", "请假事由");
        headerMap.put("daynum", "天数");
        headerMap.put("stuNo", "学号");
        headerMap.put("applytime", "请假时间");
        headerMap.put("status", "状态");
        headerMap.put("audittime", "审核时间");
        headerMap.put("opinion", "审核意见");

        // 动态计算有多少列被选中
        int columnCount = 0;
        for (String key : orderedKeys) {
            if (checkedAllObject.getBoolean(key)) {
                columnCount++;
            }
        }

        // 动态合并第一行的单元格，范围从列0到（columnCount - 1）
// 合并单元格之前，检查columnCount是否大于1
        if (columnCount > 1) {
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, columnCount - 1));
        }

        // 设置列宽，使其均匀分布或根据需要手动调整
        int[] columnWidths = {5000, 3000, 6000, 2000, 60000, 4000, 3000, 3000, 7000};
        for (int k = 0; k < columnCount; k++) {
            sheet.setColumnWidth(k, columnWidths[k]); // 动态设置每列宽度
        }

        // 创建表头并设置边框样式
        CellStyle borderStyle = workbook.createCellStyle();
        borderStyle.setBorderTop(BorderStyle.THIN);
        borderStyle.setBorderBottom(BorderStyle.THIN);
        borderStyle.setBorderLeft(BorderStyle.THIN);
        borderStyle.setBorderRight(BorderStyle.THIN);
        borderStyle.setAlignment(HorizontalAlignment.CENTER);
        borderStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        Row headerRow = sheet.createRow(1);
        int i = 0;
        // 按照 orderedKeys 顺序动态创建表头
        for (String key : orderedKeys) {
            if (checkedAllObject.getBoolean(key)) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headerMap.get(key));
                cell.setCellStyle(borderStyle);
                i++;
            }
        }

        // 填充数据行
        int rowNum = 2; // 第2行开始填充数据
        CellStyle dataCellStyle = workbook.createCellStyle();
        dataCellStyle.setAlignment(HorizontalAlignment.CENTER);
        dataCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        for (Object item : pageResult.getRecords()) {
            Row row = sheet.createRow(rowNum++);
            Leave leave = (Leave) item;
            int j = 0;

            // 按照 orderedKeys 顺序填充数据
            for (String key : orderedKeys) {
                if (checkedAllObject.getBoolean(key)) {
                    Cell cell = row.createCell(j);
                    switch (key) {
                        case "leaveID":
                            cell.setCellValue(leave.getLeaveID());
                            break;
                        case "courseID":
                            cell.setCellValue(leave.getCourseID());
                            break;
                        case "reason":
                            cell.setCellValue(leave.getReason());
                            break;
                        case "daynum":
                            cell.setCellValue(leave.getDaynum());
                            break;
                        case "stuNo":
                            cell.setCellValue(leave.getStuNo());
                            break;
                        case "applytime":
                            cell.setCellValue(leave.getApplytime());
                            break;
                        case "status":
                            cell.setCellValue(leave.getStatus());
                            break;
                        case "audittime":
                            cell.setCellValue(leave.getAudittime());
                            break;
                        case "opinion":
                            cell.setCellValue(leave.getOpinion());
                            break;
                    }
                    cell.setCellStyle(dataCellStyle);
                    j++;
                }
            }
        }

        // 将Workbook转换为byte数组
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            workbook.write(bos);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        byte[] bytes = bos.toByteArray();

        // 设置响应头，指定文件名和类型
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "请假名单.xlsx");

        // 返回ResponseEntity，包含byte数组和响应头
        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }


}
